<template>
  <el-dialog
    :title="`数据生成器`"
    v-model="drawerVisible"
    :draggable="true"
    :overflow="true"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    top="30px"
    width="70%"
    :destroy-on-close="true"
  >
    <el-form ref="ruleFormRef" style="overflow-y: auto" label-width="120px" label-position="left">
      <div class="generator-form">
        <!-- 参数配置区域 -->
        <div class="config-section">
          <h3 class="section-title">
            <el-icon><Setting /></el-icon>
            生成配置
          </h3>
          <el-row :gutter="20">
            <el-col :span="12">
              <el-form-item label="数据类型:">
                <el-select v-model="selectedType" placeholder="请选择数据类型" @change="onTypeChange">
                  <el-option v-for="item in dataTypes" :key="item.value" :label="item.label" :value="item.value" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="生成数量:">
                <el-input-number v-model="generateCount" :min="1" :max="1000" controls-position="right" placeholder="1-1000" />
              </el-form-item>
            </el-col>
          </el-row>

          <!-- 动态配置项 -->
          <div v-if="currentConfig.length > 0" class="dynamic-config">
            <el-row :gutter="20" v-for="config in currentConfig" :key="config.key">
              <el-col :span="12">
                <el-form-item :label="config.label">
                  <el-input v-if="config.type === 'input'" v-model="configValues[config.key]" :placeholder="config.placeholder" />
                  <el-input-number
                    v-else-if="config.type === 'number'"
                    v-model="configValues[config.key]"
                    :min="config.min"
                    :max="config.max"
                    controls-position="right"
                  />
                  <el-select
                    v-else-if="config.type === 'select'"
                    v-model="configValues[config.key]"
                    :placeholder="config.placeholder"
                  >
                    <el-option v-for="option in config.options" :key="option.value" :label="option.label" :value="option.value" />
                  </el-select>
                  <el-switch
                    v-else-if="config.type === 'switch'"
                    v-model="configValues[config.key]"
                    :active-text="config.activeText"
                    :inactive-text="config.inactiveText"
                  />
                </el-form-item>
              </el-col>
            </el-row>
          </div>

          <el-row>
            <el-col :span="24">
              <el-form-item>
                <el-button type="primary" @click="generateData" :loading="generating">
                  <el-icon><Mic /></el-icon>
                  生成数据
                </el-button>
                <el-button @click="clearResult">
                  <el-icon><Delete /></el-icon>
                  清空结果
                </el-button>
                <el-button @click="copyResult" :disabled="!resultData">
                  <el-icon><CopyDocument /></el-icon>
                  复制结果
                </el-button>
              </el-form-item>
            </el-col>
          </el-row>
        </div>

        <!-- 结果展示区域 -->
        <div class="result-section">
          <h3 class="section-title">
            <el-icon><List /></el-icon>
            生成结果
            <span v-if="resultData" class="result-count">({{ resultData.split("\n").length - 1 }}条)</span>
          </h3>
          <el-input type="textarea" :rows="15" placeholder="生成的数据将在这里显示..." v-model="resultData" readonly />
        </div>
      </div>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="drawerVisible = false">关闭</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts" name="DataGenerator">
import { ref, reactive, computed } from "vue";
import { ElMessage } from "element-plus";
import { Setting, Mic, Delete, CopyDocument, List } from "@element-plus/icons-vue";

interface DrawerProps {}

const drawerVisible = ref(false);
const drawerProps = ref<DrawerProps>({});
const generating = ref(false);
const selectedType = ref("");
const generateCount = ref(10);
const resultData = ref("");
const configValues = reactive<Record<string, any>>({});

// 数据类型配置
const dataTypes = [
  { label: "手机号", value: "phone" },
  { label: "身份证号", value: "idCard" },
  { label: "姓名", value: "name" },
  { label: "地址", value: "address" },
  { label: "邮箱", value: "email" },
  { label: "标题", value: "title" },
  { label: "文章内容", value: "content" },
  { label: "用户名", value: "username" },
  { label: "密码", value: "password" },
  { label: "URL链接", value: "url" },
  { label: "IP地址", value: "ip" },
  { label: "MAC地址", value: "mac" },
  { label: "UUID", value: "uuid" },
  { label: "银行卡号", value: "bankCard" },
  { label: "车牌号", value: "plateNumber" }
];

// 动态配置项
const typeConfigs = {
  phone: [
    {
      key: "format",
      label: "号码格式:",
      type: "select",
      placeholder: "选择格式",
      options: [
        { label: "13812345678", value: "normal" },
        { label: "138-1234-5678", value: "dash" },
        { label: "138 1234 5678", value: "space" }
      ]
    }
  ],
  idCard: [
    {
      key: "format",
      label: "证件格式:",
      type: "select",
      placeholder: "选择格式",
      options: [
        { label: "18位身份证", value: "18" },
        { label: "15位身份证", value: "15" }
      ]
    }
  ],
  name: [
    {
      key: "type",
      label: "姓名类型:",
      type: "select",
      placeholder: "选择类型",
      options: [
        { label: "中文姓名", value: "chinese" },
        { label: "英文姓名", value: "english" }
      ]
    },
    {
      key: "length",
      label: "姓名长度:",
      type: "select",
      placeholder: "选择长度",
      options: [
        { label: "2-3字", value: "short" },
        { label: "3-4字", value: "long" }
      ]
    }
  ],
  address: [
    {
      key: "level",
      label: "地址级别:",
      type: "select",
      placeholder: "选择级别",
      options: [
        { label: "省市区", value: "province" },
        { label: "详细地址", value: "detail" }
      ]
    }
  ],
  email: [{ key: "domain", label: "邮箱域名:", type: "input", placeholder: "留空使用随机域名" }],
  title: [
    { key: "length", label: "标题长度:", type: "number", min: 5, max: 50, placeholder: "5-50字符" },
    {
      key: "type",
      label: "标题类型:",
      type: "select",
      placeholder: "选择类型",
      options: [
        { label: "新闻标题", value: "news" },
        { label: "技术文章", value: "tech" },
        { label: "生活随笔", value: "life" }
      ]
    }
  ],
  content: [
    { key: "length", label: "内容长度:", type: "number", min: 50, max: 1000, placeholder: "50-1000字符" },
    {
      key: "type",
      label: "内容类型:",
      type: "select",
      placeholder: "选择类型",
      options: [
        { label: "新闻内容", value: "news" },
        { label: "技术文档", value: "tech" },
        { label: "产品描述", value: "product" }
      ]
    }
  ],
  username: [
    { key: "length", label: "用户名长度:", type: "number", min: 3, max: 20, placeholder: "3-20字符" },
    { key: "includeNumber", label: "包含数字:", type: "switch", activeText: "是", inactiveText: "否" }
  ],
  password: [
    { key: "length", label: "密码长度:", type: "number", min: 6, max: 32, placeholder: "6-32字符" },
    { key: "includeSymbol", label: "包含符号:", type: "switch", activeText: "是", inactiveText: "否" },
    { key: "includeUppercase", label: "包含大写:", type: "switch", activeText: "是", inactiveText: "否" }
  ],
  url: [
    {
      key: "protocol",
      label: "协议类型:",
      type: "select",
      placeholder: "选择协议",
      options: [
        { label: "http://", value: "http" },
        { label: "https://", value: "https" },
        { label: "随机", value: "random" }
      ]
    }
  ],
  ip: [
    {
      key: "type",
      label: "IP类型:",
      type: "select",
      placeholder: "选择类型",
      options: [
        { label: "IPv4", value: "ipv4" },
        { label: "IPv6", value: "ipv6" }
      ]
    }
  ],
  mac: [
    {
      key: "format",
      label: "MAC格式:",
      type: "select",
      placeholder: "选择格式",
      options: [
        { label: "aa:bb:cc:dd:ee:ff", value: "colon" },
        { label: "aa-bb-cc-dd-ee-ff", value: "dash" },
        { label: "aabbccddeeff", value: "none" }
      ]
    }
  ],
  uuid: [
    {
      key: "format",
      label: "UUID格式:",
      type: "select",
      placeholder: "选择格式",
      options: [
        { label: "标准格式", value: "standard" },
        { label: "无连字符", value: "simple" },
        { label: "大写", value: "uppercase" }
      ]
    }
  ],
  bankCard: [
    {
      key: "type",
      label: "卡片类型:",
      type: "select",
      placeholder: "选择类型",
      options: [
        { label: "储蓄卡", value: "debit" },
        { label: "信用卡", value: "credit" },
        { label: "随机", value: "random" }
      ]
    }
  ],
  plateNumber: [
    {
      key: "type",
      label: "车牌类型:",
      type: "select",
      placeholder: "选择类型",
      options: [
        { label: "普通车牌", value: "normal" },
        { label: "新能源", value: "newEnergy" }
      ]
    }
  ]
};

// 当前选中类型的配置
const currentConfig = computed(() => {
  return typeConfigs[selectedType.value] || [];
});

// 类型变化时重置配置值
const onTypeChange = () => {
  Object.keys(configValues).forEach(key => {
    delete configValues[key];
  });
  // 设置默认值
  currentConfig.value.forEach(config => {
    if (config.type === "number") {
      configValues[config.key] = config.min || 10;
    } else if (config.type === "switch") {
      configValues[config.key] = false;
    } else if (config.options) {
      configValues[config.key] = config.options[0].value;
    } else {
      configValues[config.key] = "";
    }
  });
};

// 数据生成器函数
const generators = {
  phone: (config: any) => {
    const prefixes = [
      "130",
      "131",
      "132",
      "133",
      "134",
      "135",
      "136",
      "137",
      "138",
      "139",
      "150",
      "151",
      "152",
      "153",
      "155",
      "156",
      "157",
      "158",
      "159",
      "180",
      "181",
      "182",
      "183",
      "184",
      "185",
      "186",
      "187",
      "188",
      "189"
    ];
    const prefix = prefixes[Math.floor(Math.random() * prefixes.length)];
    const suffix = Math.floor(Math.random() * 100000000)
      .toString()
      .padStart(8, "0");
    const phone = prefix + suffix;

    switch (config.format) {
      case "dash":
        return phone.replace(/(\d{3})(\d{4})(\d{4})/, "$1-$2-$3");
      case "space":
        return phone.replace(/(\d{3})(\d{4})(\d{4})/, "$1 $2 $3");
      default:
        return phone;
    }
  },

  idCard: (config: any) => {
    const areas = ["110101", "110102", "110105", "110106", "110107", "110108", "110109", "110111"];
    const area = areas[Math.floor(Math.random() * areas.length)];
    const year = 1950 + Math.floor(Math.random() * 70);
    const month = (1 + Math.floor(Math.random() * 12)).toString().padStart(2, "0");
    const day = (1 + Math.floor(Math.random() * 28)).toString().padStart(2, "0");
    const sequence = Math.floor(Math.random() * 999)
      .toString()
      .padStart(3, "0");

    if (config.format === "15") {
      return area + year.toString().substr(2) + month + day + sequence.substr(0, 2);
    }

    const front17 = area + year + month + day + sequence;
    const checkCodes = "10X98765432";
    const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
    let sum = 0;
    for (let i = 0; i < 17; i++) {
      sum += parseInt(front17[i]) * weights[i];
    }
    const checkCode = checkCodes[sum % 11];
    return front17 + checkCode;
  },

  name: (config: any) => {
    if (config.type === "english") {
      const firstNames = [
        "James",
        "John",
        "Robert",
        "Michael",
        "William",
        "David",
        "Richard",
        "Joseph",
        "Thomas",
        "Christopher",
        "Mary",
        "Patricia",
        "Jennifer",
        "Linda",
        "Elizabeth",
        "Barbara",
        "Susan",
        "Jessica",
        "Sarah",
        "Karen"
      ];
      const lastNames = ["Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez"];
      const firstName = firstNames[Math.floor(Math.random() * firstNames.length)];
      const lastName = lastNames[Math.floor(Math.random() * lastNames.length)];
      return `${firstName} ${lastName}`;
    }

    const surnames = [
      "王",
      "李",
      "张",
      "刘",
      "陈",
      "杨",
      "赵",
      "黄",
      "周",
      "吴",
      "徐",
      "孙",
      "胡",
      "朱",
      "高",
      "林",
      "何",
      "郭",
      "马",
      "罗"
    ];
    const names = [
      "伟",
      "芳",
      "娜",
      "秀英",
      "敏",
      "静",
      "丽",
      "强",
      "磊",
      "军",
      "洋",
      "勇",
      "艳",
      "杰",
      "娟",
      "涛",
      "明",
      "超",
      "秀兰",
      "霞"
    ];

    const surname = surnames[Math.floor(Math.random() * surnames.length)];
    const nameLength = config.length === "long" ? (Math.random() > 0.5 ? 2 : 1) : 1;
    let name = "";
    for (let i = 0; i < nameLength; i++) {
      name += names[Math.floor(Math.random() * names.length)];
    }
    return surname + name;
  },

  address: (config: any) => {
    const provinces = ["北京市", "上海市", "广东省", "浙江省", "江苏省", "山东省", "河南省", "湖北省", "湖南省", "四川省"];
    const cities = ["海淀区", "朝阳区", "西城区", "东城区", "丰台区", "石景山区", "门头沟区", "房山区", "通州区", "顺义区"];
    const streets = [
      "中关村大街",
      "王府井大街",
      "长安街",
      "建国门外大街",
      "复兴门外大街",
      "西单北大街",
      "东单北大街",
      "前门大街"
    ];

    const province = provinces[Math.floor(Math.random() * provinces.length)];
    const city = cities[Math.floor(Math.random() * cities.length)];
    const street = streets[Math.floor(Math.random() * streets.length)];
    const number = Math.floor(Math.random() * 999) + 1;

    if (config.level === "detail") {
      return `${province}${city}${street}${number}号`;
    }
    return `${province}${city}`;
  },

  email: (config: any) => {
    const domains = ["gmail.com", "163.com", "qq.com", "sina.com", "hotmail.com", "yahoo.com"];
    const userPart = Math.random().toString(36).substring(2, 10);
    const domain = config.domain || domains[Math.floor(Math.random() * domains.length)];
    return `${userPart}@${domain}`;
  },

  title: (config: any) => {
    const newsTitles = ["突破性技术发布", "市场分析报告", "行业发展趋势", "创新产品上线", "重要会议召开"];
    const techTitles = ["Vue3实战教程", "TypeScript进阶指南", "微服务架构设计", "前端性能优化", "数据库设计规范"];
    const lifeTitles = ["生活小窍门", "旅行见闻录", "美食制作心得", "读书笔记分享", "健康生活指南"];

    let titles = newsTitles;
    if (config.type === "tech") titles = techTitles;
    else if (config.type === "life") titles = lifeTitles;

    const baseTitle = titles[Math.floor(Math.random() * titles.length)];
    const targetLength = config.length || 20;
    const suffixes = ["详解", "指南", "实践", "分析", "总结", "心得", "技巧", "方法"];

    let title = baseTitle;
    while (title.length < targetLength) {
      title += suffixes[Math.floor(Math.random() * suffixes.length)];
    }

    return title.substring(0, targetLength);
  },

  content: (config: any) => {
    const newsContent =
      "今日，相关部门发布了最新的政策解读，对于推动行业发展具有重要意义。专家表示，这项政策的实施将有效促进市场的健康发展，为企业带来新的机遇。";
    const techContent =
      "在现代软件开发中，选择合适的技术栈对项目成功至关重要。本文将详细介绍各种技术方案的优缺点，帮助开发者做出明智的选择。";
    const productContent =
      "这款产品采用了先进的技术设计，具有出色的性能表现和用户体验。产品特色包括高效率、低功耗、易操作等优点，适合各种使用场景。";

    let baseContent = newsContent;
    if (config.type === "tech") baseContent = techContent;
    else if (config.type === "product") baseContent = productContent;

    const targetLength = config.length || 200;
    let content = baseContent;

    while (content.length < targetLength) {
      content += baseContent;
    }

    return content.substring(0, targetLength);
  },

  username: (config: any) => {
    const chars = "abcdefghijklmnopqrstuvwxyz";
    const numbers = "0123456789";
    const length = config.length || 8;

    let username = "";
    for (let i = 0; i < length; i++) {
      if (config.includeNumber && Math.random() > 0.7) {
        username += numbers[Math.floor(Math.random() * numbers.length)];
      } else {
        username += chars[Math.floor(Math.random() * chars.length)];
      }
    }
    return username;
  },

  password: (config: any) => {
    const lower = "abcdefghijklmnopqrstuvwxyz";
    const upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    const numbers = "0123456789";
    const symbols = "!@#$%^&*()_+-=[]{}|;:,.<>?";

    let chars = lower + numbers;
    if (config.includeUppercase) chars += upper;
    if (config.includeSymbol) chars += symbols;

    const length = config.length || 12;
    let password = "";
    for (let i = 0; i < length; i++) {
      password += chars[Math.floor(Math.random() * chars.length)];
    }
    return password;
  },

  url: (config: any) => {
    const domains = ["example.com", "test.org", "demo.net", "sample.io", "mock.dev"];
    const paths = ["api", "users", "products", "services", "about", "contact"];

    const protocol = config.protocol === "random" ? (Math.random() > 0.5 ? "https" : "http") : config.protocol;
    const domain = domains[Math.floor(Math.random() * domains.length)];
    const path = paths[Math.floor(Math.random() * paths.length)];

    return `${protocol}://${domain}/${path}`;
  },

  ip: (config: any) => {
    if (config.type === "ipv6") {
      const parts: string[] = [];
      for (let i = 0; i < 8; i++) {
        parts.push(
          Math.floor(Math.random() * 65536)
            .toString(16)
            .padStart(4, "0")
        );
      }
      return parts.join(":");
    }

    const parts: number[] = [];
    for (let i = 0; i < 4; i++) {
      parts.push(Math.floor(Math.random() * 256));
    }
    return parts.join(".");
  },

  mac: (config: any) => {
    const hex = "0123456789ABCDEF";
    const parts: string[] = [];

    for (let i = 0; i < 6; i++) {
      let part = "";
      for (let j = 0; j < 2; j++) {
        part += hex[Math.floor(Math.random() * hex.length)];
      }
      parts.push(part);
    }

    switch (config.format) {
      case "dash":
        return parts.join("-");
      case "none":
        return parts.join("");
      default:
        return parts.join(":");
    }
  },

  uuid: (config: any) => {
    const template = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";

    let uuid = template.replace(/[xy]/g, c => {
      const r = (Math.random() * 16) | 0;
      const v = c === "x" ? r : (r & 0x3) | 0x8;
      return v.toString(16);
    });

    if (config.format === "simple") {
      uuid = uuid.replace(/-/g, "");
    } else if (config.format === "uppercase") {
      uuid = uuid.toUpperCase();
    }

    return uuid;
  },

  bankCard: (config: any) => {
    const prefixes = {
      debit: ["6225", "6226", "6227", "6228"],
      credit: ["4367", "5187", "5254", "5267"]
    };

    const type = config.type === "random" ? (Math.random() > 0.5 ? "debit" : "credit") : config.type;
    const prefixList = prefixes[type];
    const prefix = prefixList[Math.floor(Math.random() * prefixList.length)];

    let number = prefix;
    for (let i = 0; i < 12; i++) {
      number += Math.floor(Math.random() * 10);
    }

    return number;
  },

  plateNumber: (config: any) => {
    const provinces = [
      "京",
      "津",
      "沪",
      "渝",
      "冀",
      "豫",
      "云",
      "辽",
      "黑",
      "湘",
      "皖",
      "鲁",
      "新",
      "苏",
      "浙",
      "赣",
      "鄂",
      "桂",
      "甘",
      "晋",
      "蒙",
      "陕",
      "吉",
      "闽",
      "贵",
      "粤",
      "青",
      "藏",
      "川",
      "宁",
      "琼"
    ];
    const letters = "ABCDEFGHJKLMNPQRSTUVWXYZ";
    const numbers = "0123456789";

    const province = provinces[Math.floor(Math.random() * provinces.length)];
    const letter = letters[Math.floor(Math.random() * letters.length)];

    let plate = province + letter;

    if (config.type === "newEnergy") {
      // 新能源车牌 8位
      for (let i = 0; i < 6; i++) {
        if (i < 2) {
          plate += numbers[Math.floor(Math.random() * numbers.length)];
        } else {
          plate +=
            Math.random() > 0.5
              ? numbers[Math.floor(Math.random() * numbers.length)]
              : letters[Math.floor(Math.random() * letters.length)];
        }
      }
    } else {
      // 普通车牌 7位
      for (let i = 0; i < 5; i++) {
        plate +=
          Math.random() > 0.3
            ? numbers[Math.floor(Math.random() * numbers.length)]
            : letters[Math.floor(Math.random() * letters.length)];
      }
    }

    return plate;
  }
};

// 生成数据
const generateData = async () => {
  if (!selectedType.value) {
    ElMessage.warning("请先选择数据类型");
    return;
  }

  generating.value = true;

  try {
    const generator = generators[selectedType.value];
    if (!generator) {
      ElMessage.error("暂不支持该数据类型");
      return;
    }

    const results: string[] = [];
    for (let i = 0; i < generateCount.value; i++) {
      const data = generator(configValues);
      results.push(data);
    }

    resultData.value = results.join("\n");
    ElMessage.success(`成功生成 ${results.length} 条数据`);
  } catch (error) {
    ElMessage.error("生成数据失败");
    console.error(error);
  } finally {
    generating.value = false;
  }
};

// 清空结果
const clearResult = () => {
  resultData.value = "";
};

// 复制结果
const copyResult = async () => {
  if (!resultData.value) {
    ElMessage.warning("没有可复制的内容");
    return;
  }

  try {
    await navigator.clipboard.writeText(resultData.value);
    ElMessage.success("复制成功");
  } catch (error) {
    ElMessage.error("复制失败");
  }
};

// 接收父组件传过来的参数
const acceptParams = async (params: DrawerProps) => {
  drawerProps.value = params;
  drawerVisible.value = true;
};

defineExpose({
  acceptParams
});
</script>

<style lang="scss" scoped>
.generator-form {
  display: flex;
  flex-direction: column;
  gap: 24px;
  .config-section,
  .result-section {
    padding: 20px;
    background: var(--el-bg-color-page);
    border: 1px solid var(--el-border-color-lighter);
    border-radius: 8px;
    .section-title {
      display: flex;
      gap: 8px;
      align-items: center;
      margin: 0 0 16px;
      font-size: 16px;
      font-weight: 600;
      color: var(--el-text-color-primary);
      .el-icon {
        color: var(--el-color-primary);
      }
      .result-count {
        font-size: 14px;
        font-weight: normal;
        color: var(--el-text-color-regular);
      }
    }
  }
  .dynamic-config {
    padding-top: 16px;
    margin-top: 16px;
    border-top: 1px solid var(--el-border-color-lighter);
  }
}
.dialog-footer {
  display: flex;
  justify-content: flex-end;
}

// 响应式设计
@media (width <= 768px) {
  .generator-form {
    gap: 16px;
    .config-section,
    .result-section {
      padding: 16px;
    }
  }
}
</style>
